using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Domain.MainModule.Entities;
using Presentation.Web.UI.ActionResults;
using Presentation.Web.UI.Attibutes;
using Presentation.Web.UI.ViewModels;
using Presentation.Web.ViewModels;
using Application.MainModule.DinnerManagement;
using Presentation.Web.Core.Pagination;

namespace Presentation.Web.UI.Controllers
{
    [HandleErrorWithELMAH]
    public class DinnersController : Controller
    {

        private readonly IDinnerManagementService _dinnerService;
        private WebIdentity _webIdentity;
        private WebIdentity WebIdentity
        {
            get { return (_webIdentity ?? User.Identity as WebIdentity); }
        }

        public DinnersController(IDinnerManagementService dinnerService)
        {
            _dinnerService = dinnerService;
            _webIdentity = null;
        }

        //
        // GET: /Dinners/
        //      /Dinners/Page/2
        //      /Dinners?q=term
        public ActionResult Index(string q, int? page, int? pageSize = 25)
        {
            IEnumerable<Dinners> dinners = null;
            //Searching?
            if (!string.IsNullOrWhiteSpace(q))
                dinners = _dinnerService.FindDinnersByText(q).OrderBy(d => d.EventDate);
            else
                dinners = _dinnerService.FindUpcomingDinners();

            int pageIndex = page ?? 1;
            return View(dinners.AsPagination(pageIndex, pageSize.Value));
        }

        //
        // GET: /Dinners/Details/5

        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new FileNotFoundResult { Message = "No Dinner found due to invalid dinner id" };
            }
            Dinners dinner = _dinnerService.FindDinner(id.Value);

            if (dinner == null)
            {
                return new FileNotFoundResult { Message = "No Dinner found for that id" };
            }
            return View(dinner);
        }

        //
        // GET: /Dinners/Edit/5

        [Authorize]
        public ActionResult Edit(int id)
        {

            Dinners dinner = _dinnerService.FindDinner(id);

            if (dinner == null)
                return View("NotFound");

            if (!dinner.IsHostedBy(User.Identity.Name))
                return View("InvalidOwner");

            return View(dinner);
        }

        //
        // POST: /Dinners/Edit/5
        [HttpPost, Authorize, ValidateAntiForgeryToken]
        public ActionResult Edit(int id, FormCollection collection)
        {

            Dinners dinner = _dinnerService.FindDinner(id);

            if (!dinner.IsHostedBy(User.Identity.Name))
                return View("InvalidOwner");
            try
            {
                UpdateModel(dinner);
                _dinnerService.Save();
                return RedirectToAction("Details", new { id = dinner.DinnerID });
            }
            catch
            {
                return View(dinner);
            }
        }

        //
        // GET: /Dinners/Create

        [Authorize]
        public ActionResult Create()
        {
            Dinners dinner = new Dinners()
            {
                EventDate = DateTime.Now.AddDays(7)
            };

            return View(dinner);
        }
        //
        // POST: /Dinners/Create

        [HttpPost, Authorize, ValidateAntiForgeryToken]
        public ActionResult Create(Dinners dinner)
        {

            if (ModelState.IsValid)
            {
                dinner.HostedById = this.WebIdentity.Name;
                dinner.HostedBy = this.WebIdentity.CustomerName;

                var rsvp = new RSVPs
                               {AttendeeNameId = this.WebIdentity.Name, AttendeeName = this.WebIdentity.CustomerName};
                dinner.RSVPs.Add(rsvp);

                _dinnerService.InsertOrUpdateDinner(dinner);
                _dinnerService.Save();
                return RedirectToAction("Details", new { id = dinner.DinnerID });
            }

            return View(dinner);
        }

        //
        // HTTP GET: /Dinners/Delete/1

        [Authorize, ValidateAntiForgeryToken]
        public ActionResult Delete(int id)
        {
            Dinners dinner = _dinnerService.FindDinner(id);

            if (dinner == null)
                return View("NotFound");
            if (!dinner.IsHostedBy(User.Identity.Name))
                return View("InvalidOwner");

            return View(dinner);
        }

        // 
        // HTTP POST: /Dinners/Delete/1

        [HttpPost, Authorize]
        public ActionResult Delete(int id, string confirmButton)
        {

            Dinners dinner = _dinnerService.FindDinner(id);

            if (dinner == null)
                return View("NotFound");

            if (!dinner.IsHostedBy(User.Identity.Name))
                return View("InvalidOwner");

            _dinnerService.DeleteDinner(id);
            _dinnerService.Save();

            return View("Deleted");
        }


        protected override void HandleUnknownAction(string actionName)
        {
            throw new HttpException(404, "Action not found");
        }

        public ActionResult Lost()
        {
            return View();
        }

        public ActionResult Trouble()
        {
            return View("Error");
        }

        [Authorize]
        public ActionResult My()
        {
            _webIdentity = this.WebIdentity;
            var userDinners = _dinnerService.FindMyDinners(_webIdentity.Name);
            return View(userDinners);
        }

        public ActionResult WebSlicePopular()
        {
            ViewData["Title"] = "Popular Nerd Dinners";
            var model = from dinner in _dinnerService.FindUpcomingDinners()
                        orderby dinner.RSVPs.Count descending
                        select dinner;
            return View("WebSlice", model.Take(5));
        }

        public ActionResult WebSliceUpcoming()
        {
            ViewData["Title"] = "Upcoming Nerd Dinners";
            DateTime d = DateTime.Now.AddMonths(2);
            var model = from dinner in _dinnerService.FindUpcomingDinners()
                        where dinner.EventDate < d
                        orderby dinner.EventDate descending
                        select dinner;
            return View("WebSlice", model.Take(5));
        }

    }
}